#ifndef _SIGNAL_H
#define _SIGNAL_H

#include <sys/types.h>

typedef int sig_atomic_t;
typedef unsigned int sigset_t;		/* 32 bits */

#define _NSIG             32
#define NSIG		_NSIG

#define SIGHUP		 1  /* https://www.cnblogs.com/klb561/p/12051027.html */
#define SIGINT		 2
#define SIGQUIT		 3
#define SIGILL		 4
#define SIGTRAP		 5
#define SIGABRT		 6
#define SIGIOT		 6
#define SIGUNUSED	 7
#define SIGFPE		 8
#define SIGKILL		 9
#define SIGUSR1		10
#define SIGSEGV		11
#define SIGUSR2		12
#define SIGPIPE		13
#define SIGALRM		14
#define SIGTERM		15
#define SIGSTKFLT	16
#define SIGCHLD		17
#define SIGCONT		18
#define SIGSTOP		19
#define SIGTSTP		20
#define SIGTTIN		21
#define SIGTTOU		22

/* Ok, I haven't implemented sigactions, but trying to keep headers POSIX */
#define SA_NOCLDSTOP	1
#define SA_NOMASK	0x4000000  /* 在触发处理函数的信号处理过程中，不要阻止再次接收此信号（缺省情况下，正在处理中的信号会被系统阻塞) */
#define SA_ONESHOT	0x80000000 /* 设置的信号处理函数，仅仅起作用一次。用完了一次后，就设置回默认行为，即当调用信号处理函数时，将信号的处理函数重置为缺省值，类似于SA_RESETHAND */

#define SIG_BLOCK          0	/* for blocking signals */
#define SIG_UNBLOCK        1	/* for unblocking signals */
#define SIG_SETMASK        2	/* for setting the signal mask */

#define SIG_DFL		((void (*)(int))0)	/* default signal handling */  /* 将 数值0 类型转换成函数，这个指针值是实际程序中不可能出现的函数地址值,因此在 signal()函数中就可以根据这两个特殊的指针值来判断是否使用默认信号处理句柄或忽略对信号的处理 */
#define SIG_IGN		((void (*)(int))1)	/* ignore signal */

struct sigaction {
	void (*sa_handler)(int); /*信号处理句柄（信号处理函数指针）*/
	sigset_t sa_mask; /*表示一个信号集，在调用该信号处理句柄之前，这一信号集要加进进程的信号屏蔽字(blocked)中。仅当从信号信号句柄返回时再将进程的信号屏蔽字复位为原先值。*/
	int sa_flags;  /*信号行为标识，可以是SA_NOCLDSTOP、SA_NOMASK、SA_ONESHOT等标置位(bit)或组合*/
	void (*sa_restorer)(void); /*信号恢复函数指针（系统内部使用）,由 Libc 函数库提供，用于在信号处理程序结束后清理用户态堆栈*/
};

void (*signal(int _sig, void (*_func)(int)))(int);
int raise(int sig);
int kill(pid_t pid, int sig);
int sigaddset(sigset_t *mask, int signo);
int sigdelset(sigset_t *mask, int signo);
int sigemptyset(sigset_t *mask);
int sigfillset(sigset_t *mask);
int sigismember(sigset_t *mask, int signo); /* 1 - is, 0 - not, -1 error */
int sigpending(sigset_t *set);
int sigprocmask(int how, sigset_t *set, sigset_t *oldset);
int sigsuspend(sigset_t *sigmask);
int sigaction(int sig, struct sigaction *act, struct sigaction *oldact);

#endif /* _SIGNAL_H */
